In [3]:
import pandas as pd
import numpy as np
import datetime as dt
In [4]:
stock_df = pd.read_csv('Amazon.csv')
stock_df.head()
Out[4]:
Date Open High Low Close Volume Adj Close
0 1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500
1 1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999
2 1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500
3 1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001
4 1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498
In [5]:
stock_df.isnull().sum()
Out[5]:
Date         0
Open         0
High         0
Low          0
Close        0
Volume       0
Adj Close    0
dtype: int64
In [6]:
stock_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1250 entries, 0 to 1249
Data columns (total 7 columns):
 #   Column     Non-Null Count  Dtype  
---  ------     --------------  -----  
 0   Date       1250 non-null   object 
 1   Open       1250 non-null   float64
 2   High       1250 non-null   float64
 3   Low        1250 non-null   float64
 4   Close      1250 non-null   float64
 5   Volume     1250 non-null   int64  
 6   Adj Close  1250 non-null   float64
dtypes: float64(5), int64(1), object(1)
memory usage: 68.5+ KB
In [7]:
stock_df['Daily Return'] = stock_df['Adj Close'].pct_change(1)*100
In [8]:
stock_df.head(10)
Out[8]:
Date Open High Low Close Volume Adj Close Daily Return
0 1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500 NaN
1 1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999 1.277531
2 1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500 0.447601
3 1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001 1.616252
4 1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498 1.442468
5 1/9/2018 62.845001 62.966499 62.088001 62.634998 73226000 62.634998 0.467571
6 1/10/2018 62.257500 62.716499 61.861500 62.716499 53720000 62.716499 0.130121
7 1/11/2018 62.987000 63.838501 62.823002 63.834000 62500000 63.834000 1.781828
8 1/12/2018 63.669498 65.288002 63.669498 65.260002 108874000 65.260002 2.233923
9 1/16/2018 66.150002 66.997002 64.614998 65.242996 144414000 65.242996 -0.026059
In [9]:
stock_df['Daily Return'].replace(np.nan,0,inplace=True)
stock_df
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\1069298868.py:1: FutureWarning: A value is trying to be set on a copy of a DataFrame or Series through chained assignment using an inplace method.
The behavior will change in pandas 3.0. This inplace method will never work because the intermediate object on which we are setting values always behaves as a copy.

For example, when doing 'df[col].method(value, inplace=True)', try using 'df.method({col: value}, inplace=True)' or df[col] = df[col].method(value) instead, to perform the operation inplace on the original object.


  stock_df['Daily Return'].replace(np.nan,0,inplace=True)
Out[9]:
Date Open High Low Close Volume Adj Close Daily Return
0 1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500 0.000000
1 1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999 1.277531
2 1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500 0.447601
3 1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001 1.616252
4 1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498 1.442468
... ... ... ... ... ... ... ... ...
1245 12/12/2022 89.209999 90.580002 87.870003 90.550003 61999800 90.550003 1.638800
1246 12/13/2022 95.230003 96.250000 90.519997 92.489998 100212000 92.489998 2.142457
1247 12/14/2022 92.500000 93.459999 89.870003 91.580002 70298000 91.580002 -0.983886
1248 12/15/2022 89.889999 89.970001 87.470001 88.449997 84802900 88.449997 -3.417782
1249 12/16/2022 88.269997 89.349998 86.730003 87.860001 146044000 87.860001 -0.667039

1250 rows × 8 columns

In [10]:
stock_df.describe().round(2)
Out[10]:
Open High Low Close Volume Adj Close Daily Return
count 1250.00 1250.00 1250.00 1250.00 1.250000e+03 1250.00 1250.00
mean 120.15 121.59 118.54 120.07 8.670803e+07 120.07 0.06
std 35.66 36.04 35.23 35.59 4.077817e+07 35.59 2.25
min 58.60 59.50 58.53 59.45 1.762600e+07 59.45 -14.05
25% 89.21 89.90 88.10 89.13 5.897078e+07 89.13 -1.04
50% 108.29 111.70 106.86 108.73 7.515300e+07 108.73 0.12
75% 158.39 160.05 156.28 158.11 1.027046e+08 158.11 1.17
max 187.20 188.65 184.84 186.57 3.113460e+08 186.57 13.54
In [11]:
import plotly.express as px
In [12]:
fig = px.line(title="Amazon.com INC (AMZN) adjusted closing price[$]")
fig.add_scatter(x=stock_df['Date'], y=stock_df['Adj Close'], name= 'Adj close')
In [13]:
def financial_plot(df, title):
    fig = px.line(title=title)

    for i in df.columns[1:]:
        fig.add_scatter(x=df['Date'], y=df[i], name= i)
        fig.update_traces(line_width= 3)
        fig.update_layout({'plot_bgcolor' : "white"})

    df['Date'] = pd.to_datetime(df['Date'])
    fig.update_xaxes(tickformat="%d-%b-%Y")

    fig.show()
In [14]:
financial_plot(stock_df.drop(['Volume','Daily Return'], axis=1), "Amazon.com INC (AMZN) Stock price[$]")
In [15]:
financial_plot(stock_df.iloc[:,[0,5]], "Amazon.com INC (AMZN) Trading volume")
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\530847936.py:9: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [16]:
financial_plot(stock_df.iloc[:,[0,7]], "Amazon.com INC (AMZN) Daily return")
C:\Users\RDJ007\AppData\Local\Temp\ipykernel_14472\530847936.py:9: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [17]:
def percentage_return_classifier(percentage_return):

    if percentage_return > -0.3 and percentage_return <= 0.3:
        return 'Insignificant change'
    elif percentage_return > 0.3 and percentage_return <= 3:
        return 'Positive change'
    elif percentage_return > -3 and percentage_return <= -0.3:
        return 'Negative change'
    elif percentage_return > 3 and percentage_return <= 7:
        return 'Large positive change'
    elif percentage_return > -7 and percentage_return <= -3:
        return 'Large negative change'
    elif percentage_return > 7:
        return 'Bull run'
    elif percentage_return <= -7:
        return 'Bear sell off'
In [18]:
stock_df['Trend'] = stock_df['Daily Return'].apply(percentage_return_classifier)
stock_df
Out[18]:
Date Open High Low Close Volume Adj Close Daily Return Trend
0 1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500 0.000000 Insignificant change
1 1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999 1.277531 Positive change
2 1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500 0.447601 Positive change
3 1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001 1.616252 Positive change
4 1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498 1.442468 Positive change
... ... ... ... ... ... ... ... ... ...
1245 12/12/2022 89.209999 90.580002 87.870003 90.550003 61999800 90.550003 1.638800 Positive change
1246 12/13/2022 95.230003 96.250000 90.519997 92.489998 100212000 92.489998 2.142457 Positive change
1247 12/14/2022 92.500000 93.459999 89.870003 91.580002 70298000 91.580002 -0.983886 Negative change
1248 12/15/2022 89.889999 89.970001 87.470001 88.449997 84802900 88.449997 -3.417782 Large negative change
1249 12/16/2022 88.269997 89.349998 86.730003 87.860001 146044000 87.860001 -0.667039 Negative change

1250 rows × 9 columns

In [19]:
trend_summary = stock_df['Trend'].value_counts()
trend_summary
Out[19]:
Trend
Positive change          470
Negative change          405
Insignificant change     190
Large positive change     86
Large negative change     82
Bear sell off              9
Bull run                   8
Name: count, dtype: int64
In [20]:
import matplotlib.pyplot as plt

plt.figure(figsize=(7,8))
trend_summary.plot(kind='pie', y='trend')
Out[20]:
<Axes: ylabel='count'>
No description has been provided for this image
In [22]:
import cufflinks as cf
cf.go_offline()
In [23]:
stock_df
Out[23]:
Date Open High Low Close Volume Adj Close Daily Return Trend
0 1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500 0.000000 Insignificant change
1 1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999 1.277531 Positive change
2 1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500 0.447601 Positive change
3 1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001 1.616252 Positive change
4 1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498 1.442468 Positive change
... ... ... ... ... ... ... ... ... ...
1245 12/12/2022 89.209999 90.580002 87.870003 90.550003 61999800 90.550003 1.638800 Positive change
1246 12/13/2022 95.230003 96.250000 90.519997 92.489998 100212000 92.489998 2.142457 Positive change
1247 12/14/2022 92.500000 93.459999 89.870003 91.580002 70298000 91.580002 -0.983886 Negative change
1248 12/15/2022 89.889999 89.970001 87.470001 88.449997 84802900 88.449997 -3.417782 Large negative change
1249 12/16/2022 88.269997 89.349998 86.730003 87.860001 146044000 87.860001 -0.667039 Negative change

1250 rows × 9 columns

In [24]:
stock_df.set_index('Date', inplace=True)
stock_df
Out[24]:
Open High Low Close Volume Adj Close Daily Return Trend
Date
1/2/2018 58.599998 59.500000 58.525501 59.450500 53890000 59.450500 0.000000 Insignificant change
1/3/2018 59.415001 60.274502 59.415001 60.209999 62176000 60.209999 1.277531 Positive change
1/4/2018 60.250000 60.793499 60.233002 60.479500 60442000 60.479500 0.447601 Positive change
1/5/2018 60.875500 61.457001 60.500000 61.457001 70894000 61.457001 1.616252 Positive change
1/8/2018 61.799999 62.653999 61.601501 62.343498 85590000 62.343498 1.442468 Positive change
... ... ... ... ... ... ... ... ...
12/12/2022 89.209999 90.580002 87.870003 90.550003 61999800 90.550003 1.638800 Positive change
12/13/2022 95.230003 96.250000 90.519997 92.489998 100212000 92.489998 2.142457 Positive change
12/14/2022 92.500000 93.459999 89.870003 91.580002 70298000 91.580002 -0.983886 Negative change
12/15/2022 89.889999 89.970001 87.470001 88.449997 84802900 88.449997 -3.417782 Large negative change
12/16/2022 88.269997 89.349998 86.730003 87.860001 146044000 87.860001 -0.667039 Negative change

1250 rows × 8 columns

In [25]:
figure = cf.QuantFig(stock_df, title='Amazon.com INC (AMZN) Candlestick chart', name = 'AMZN')
figure.add_rsi(periods=14, color='java')
figure.add_bollinger_bands(periods=20, boll_std=2, colors=['magenta', 'grey'], fill=True)
#figure.add_sma(periods=[14,21], column= 'Close', colors=['magenta', 'grey'])
figure.add_sma(periods=[14, 21], column='Close', colors=['magenta', 'grey'])
#figure.add_volume()
figure.iplot(theme="white", up_color="green", down_color="red")
#figure.iplot(theme="white", up_color="green", down_color="red")
#figure.iplot(as_candlestick=True, theme="white", up_color="green", down_color="red")
In [26]:
close_prices_df = pd.read_csv("stock_prices.csv")
close_prices_df
Out[26]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 1/2/2014 19.898500 69.512543 75.620926 14.121004 27.855856 71.443314 45.640057 54.709999 20.879053 61.941517
1 1/3/2014 19.822001 69.473892 75.956062 13.835152 27.652653 72.086861 45.992889 54.560001 20.920183 61.872295
2 1/6/2014 19.681499 68.561180 75.327690 13.923512 27.960960 72.463608 46.259468 57.200001 20.940746 62.018425
3 1/7/2014 19.901501 68.785461 75.662811 13.996271 28.500000 74.001869 45.726311 57.919998 21.070980 62.618301
4 1/8/2014 20.096001 68.947906 74.850121 13.965082 28.559309 73.899841 46.157543 58.230000 21.214928 61.710812
... ... ... ... ... ... ... ... ... ... ... ...
2252 12/12/2022 90.550003 233.059998 437.049988 42.500000 93.309998 177.839996 134.210007 114.709999 52.160000 152.470001
2253 12/13/2022 92.489998 235.490005 437.190002 42.540001 95.629997 179.210007 134.080002 120.150002 53.070000 152.240005
2254 12/14/2022 91.580002 234.479996 438.440002 42.820000 95.070000 179.759995 133.410004 121.589996 54.480000 152.839996
2255 12/15/2022 88.449997 230.660004 429.790008 42.380001 90.860001 177.490005 130.100006 116.150002 53.610001 151.110001
2256 12/16/2022 87.860001 232.720001 431.089996 41.930000 90.260002 175.669998 129.289993 119.430000 51.400002 150.440002

2257 rows × 11 columns

In [27]:
daily_returns_df = close_prices_df.iloc[:,1:].pct_change()*100
daily_returns_df.replace(np.nan, 0, inplace = True)
daily_returns_df
Out[27]:
AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
1 -0.384451 -0.055602 0.443179 -2.024307 -0.729481 0.900780 0.773077 -0.274169 0.196992 -0.111753
2 -0.708814 -1.313748 -0.827284 0.638662 1.114930 0.522629 0.579608 4.838708 0.098293 0.236179
3 1.117807 0.327126 0.444884 0.522567 1.927829 2.122805 -1.152537 1.258737 0.621916 0.967255
4 0.977313 0.236162 -1.074095 -0.222838 0.208102 -0.137872 0.943073 0.535223 0.683156 -1.449240
... ... ... ... ... ... ... ... ... ... ...
2252 1.638800 2.538609 0.515165 2.607441 0.517070 1.194942 1.551152 -1.026749 0.850732 1.027036
2253 2.142457 1.042653 0.032036 0.094120 2.486336 0.770361 -0.096867 4.742396 1.744632 -0.150847
2254 -0.983886 -0.428897 0.285917 0.658201 -0.585588 0.306896 -0.499700 1.198498 2.656868 0.394108
2255 -3.417782 -1.629133 -1.972903 -1.027554 -4.428315 -1.262789 -2.481072 -4.474048 -1.596914 -1.131900
2256 -0.667039 0.893088 0.302470 -1.061823 -0.660355 -1.025414 -0.622608 2.823933 -4.122363 -0.443384

2257 rows × 10 columns

In [28]:
daily_returns_df.insert(0, "Date", close_prices_df['Date'])
In [29]:
daily_returns_df
Out[29]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 1/2/2014 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
1 1/3/2014 -0.384451 -0.055602 0.443179 -2.024307 -0.729481 0.900780 0.773077 -0.274169 0.196992 -0.111753
2 1/6/2014 -0.708814 -1.313748 -0.827284 0.638662 1.114930 0.522629 0.579608 4.838708 0.098293 0.236179
3 1/7/2014 1.117807 0.327126 0.444884 0.522567 1.927829 2.122805 -1.152537 1.258737 0.621916 0.967255
4 1/8/2014 0.977313 0.236162 -1.074095 -0.222838 0.208102 -0.137872 0.943073 0.535223 0.683156 -1.449240
... ... ... ... ... ... ... ... ... ... ... ...
2252 12/12/2022 1.638800 2.538609 0.515165 2.607441 0.517070 1.194942 1.551152 -1.026749 0.850732 1.027036
2253 12/13/2022 2.142457 1.042653 0.032036 0.094120 2.486336 0.770361 -0.096867 4.742396 1.744632 -0.150847
2254 12/14/2022 -0.983886 -0.428897 0.285917 0.658201 -0.585588 0.306896 -0.499700 1.198498 2.656868 0.394108
2255 12/15/2022 -3.417782 -1.629133 -1.972903 -1.027554 -4.428315 -1.262789 -2.481072 -4.474048 -1.596914 -1.131900
2256 12/16/2022 -0.667039 0.893088 0.302470 -1.061823 -0.660355 -1.025414 -0.622608 2.823933 -4.122363 -0.443384

2257 rows × 11 columns

In [30]:
financial_plot(close_prices_df,"Adjusted closing price [$]")
In [31]:
financial_plot(daily_returns_df,"Percentage daily returns [$]")
In [32]:
fig = px.histogram(daily_returns_df.drop(columns = ["Date"]))
fig.update_layout({'plot_bgcolor': "white"})
In [33]:
import seaborn as sns
In [34]:
plt.figure(figsize=[10,6])
sns.heatmap(daily_returns_df.drop(columns=["Date"]).corr(),annot= True, cmap="crest");
No description has been provided for this image
In [35]:
sns.pairplot(daily_returns_df);
No description has been provided for this image
In [36]:
# want to set all the prices to start at value 1 so that I can see my investments over time 
def price_scaling(raw_prices_df):
    scaled_prices_df = raw_prices_df.copy()
    for i in raw_prices_df.columns[1:]:
        scaled_prices_df[i] = raw_prices_df[i]/raw_prices_df[i][0]
    return scaled_prices_df
In [37]:
price_scaling(close_prices_df)
Out[37]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 2014-01-02 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1 2014-01-03 0.996155 0.999444 1.004432 0.979757 0.992705 1.009008 1.007731 0.997258 1.001970 0.998882
2 2014-01-06 0.989095 0.986314 0.996122 0.986014 1.003773 1.014281 1.013572 1.045513 1.002955 1.001242
3 2014-01-07 1.000151 0.989540 1.000554 0.991167 1.023124 1.035812 1.001890 1.058673 1.009192 1.010926
4 2014-01-08 1.009925 0.991877 0.989807 0.988958 1.025253 1.034384 1.011338 1.064339 1.016087 0.996275
... ... ... ... ... ... ... ... ... ... ... ...
2252 2022-12-12 4.550594 3.352776 5.779485 3.009701 3.349744 2.489246 2.940619 2.096692 2.498198 2.461515
2253 2022-12-13 4.648089 3.387734 5.781336 3.012534 3.433030 2.508422 2.937770 2.196125 2.541782 2.457802
2254 2022-12-14 4.602357 3.373204 5.797866 3.032362 3.412927 2.516121 2.923090 2.222446 2.609314 2.467489
2255 2022-12-15 4.445058 3.318250 5.683480 3.001203 3.261792 2.484347 2.850566 2.123012 2.567645 2.439559
2256 2022-12-16 4.415408 3.347885 5.700671 2.969336 3.240252 2.458872 2.832818 2.182965 2.461798 2.428743

2257 rows × 11 columns

In [38]:
financial_plot(price_scaling(close_prices_df), "Scaled prices")

Random weight generation¶

In [40]:
import random

def portfolio_weight_generation(n):
    weights = []
    for i in range(n):
        weights.append(random.random())
    
    weights = weights/np.sum(weights)
    return weights
In [41]:
weights = portfolio_weight_generation(10)
print(weights)
[0.07307595 0.03976802 0.12957574 0.09008053 0.09570124 0.10181999
 0.19088182 0.15828769 0.06655204 0.05425697]

Asset allocation¶

Assumptions:

Assuming initial $1MN investmesnts across 10 above stocks with randomly generated weights.
Assuming random weights, if specific weights are given then insert that only.

In [43]:
portfolio_df = close_prices_df.copy()
scaled_df = price_scaling(portfolio_df)
scaled_df
Out[43]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 2014-01-02 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1 2014-01-03 0.996155 0.999444 1.004432 0.979757 0.992705 1.009008 1.007731 0.997258 1.001970 0.998882
2 2014-01-06 0.989095 0.986314 0.996122 0.986014 1.003773 1.014281 1.013572 1.045513 1.002955 1.001242
3 2014-01-07 1.000151 0.989540 1.000554 0.991167 1.023124 1.035812 1.001890 1.058673 1.009192 1.010926
4 2014-01-08 1.009925 0.991877 0.989807 0.988958 1.025253 1.034384 1.011338 1.064339 1.016087 0.996275
... ... ... ... ... ... ... ... ... ... ... ...
2252 2022-12-12 4.550594 3.352776 5.779485 3.009701 3.349744 2.489246 2.940619 2.096692 2.498198 2.461515
2253 2022-12-13 4.648089 3.387734 5.781336 3.012534 3.433030 2.508422 2.937770 2.196125 2.541782 2.457802
2254 2022-12-14 4.602357 3.373204 5.797866 3.032362 3.412927 2.516121 2.923090 2.222446 2.609314 2.467489
2255 2022-12-15 4.445058 3.318250 5.683480 3.001203 3.261792 2.484347 2.850566 2.123012 2.567645 2.439559
2256 2022-12-16 4.415408 3.347885 5.700671 2.969336 3.240252 2.458872 2.832818 2.182965 2.461798 2.428743

2257 rows × 11 columns

In [44]:
initial_investment = 1000000
for i, stock in enumerate(scaled_df.columns[1:]):
    portfolio_df[stock] = weights[i] * scaled_df[stock]  * initial_investment
portfolio_df.round(1)
Out[44]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG
0 2014-01-02 73075.9 39768.0 129575.7 90080.5 95701.2 101820.0 190881.8 158287.7 66552.0 54257.0
1 2014-01-03 72795.0 39745.9 130150.0 88257.0 95003.1 102737.2 192357.5 157853.7 66683.1 54196.3
2 2014-01-06 72279.0 39223.7 129073.3 88820.7 96062.3 103274.1 193472.4 165491.8 66748.7 54324.3
3 2014-01-07 73087.0 39352.1 129647.5 89284.8 97914.3 105466.4 191242.6 167574.9 67163.8 54849.8
4 2014-01-08 73801.3 39445.0 128255.0 89085.9 98118.0 105321.0 193046.1 168471.8 67622.6 54054.9
... ... ... ... ... ... ... ... ... ... ... ...
2252 2022-12-12 332539.0 133333.3 748881.0 271115.5 320574.7 253455.0 561310.7 331880.5 166260.1 133554.4
2253 2022-12-13 339663.5 134723.5 749120.9 271370.6 328545.3 255407.5 560766.9 347619.6 169160.8 133352.9
2254 2022-12-14 336321.6 134145.7 751262.8 273156.8 326621.3 256191.4 557964.8 351785.8 173655.1 133878.5
2255 2022-12-15 324826.9 131960.2 736441.1 270350.0 312157.5 252956.2 544121.3 336046.7 170882.0 132363.1
2256 2022-12-16 322660.1 133138.8 738668.6 267479.3 310096.2 250362.4 540733.5 345536.5 163837.6 131776.2

2257 rows × 11 columns

In [45]:
def asset_allocation(df, weights,initial_investment):
    portfolio_df = df.copy()
    
    scaled_df = price_scaling(df)

    for i, stock in enumerate(scaled_df.columns[1:]):
        portfolio_df[stock] = weights[i] * scaled_df[stock] * initial_investment

    portfolio_df["Portfolio Value [$]"]=portfolio_df[portfolio_df!='Date'].sum(axis=1, numeric_only=True)

    portfolio_df["Portfolio daily return [$]"] = portfolio_df['Portfolio Value [$]'].pct_change()*100
    portfolio_df.replace(np.nan, 0, inplace=True)

    return portfolio_df
In [46]:
portfolio_df = asset_allocation(close_prices_df, weights, 1000000)
portfolio_df.round(2)
Out[46]:
Date AMZN CAT DE EXC GOOGL JNJ JPM META PFE PG Portfolio Value [$] Portfolio daily return [$]
0 2014-01-02 73075.95 39768.02 129575.74 90080.53 95701.24 101819.99 190881.82 158287.69 66552.04 54256.97 1000000.00 0.00
1 2014-01-03 72795.01 39745.91 130150.00 88257.02 95003.12 102737.17 192357.48 157853.72 66683.14 54196.34 999778.90 -0.02
2 2014-01-06 72279.03 39223.75 129073.29 88820.69 96062.34 103274.10 193472.41 165491.80 66748.68 54324.34 1008770.41 0.90
3 2014-01-07 73086.97 39352.06 129647.51 89284.84 97914.26 105466.41 191242.56 167574.90 67163.80 54849.79 1015583.11 0.68
4 2014-01-08 73801.25 39445.00 128254.98 89085.88 98118.02 105321.00 193046.12 168471.80 67622.64 54054.89 1017221.57 0.16
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2252 2022-12-12 332538.99 133333.28 748881.03 271115.46 320574.71 253455.02 561310.67 331880.49 166260.13 133554.37 3252904.15 0.99
2253 2022-12-13 339663.50 134723.48 749120.94 271370.64 328545.27 255407.54 560766.94 347619.57 169160.76 133352.91 3289731.56 1.13
2254 2022-12-14 336321.60 134145.66 751262.81 273156.80 326621.35 256191.38 557964.79 351785.78 173655.14 133878.46 3294983.77 0.16
2255 2022-12-15 324826.86 131960.25 736441.12 270349.97 312157.53 252956.22 544121.28 336046.72 170882.02 132363.09 3212105.06 -2.52
2256 2022-12-16 322660.14 133138.77 738668.64 267479.33 310096.18 250362.37 540733.54 345536.46 163837.64 131776.22 3204289.28 -0.24

2257 rows × 13 columns

In [47]:
financial_plot(portfolio_df[["Date","Portfolio daily return [$]"]], "Portfolio percentage daily return")
In [48]:
financial_plot(portfolio_df[["Date","Portfolio Value [$]"]], "Portfolio actual value return")
In [49]:
financial_plot(portfolio_df.drop(columns=['Portfolio Value [$]','Portfolio daily return [$]']),"Each stock return")
In [192]:
def simulation_engine(weights, initial_investment):

    portfolio_df = asset_allocation(close_prices_df, weights, initial_investment)

    return_on_investment = ((portfolio_df['Portfolio Value [$]'][-1:] - 
                             portfolio_df['Portfolio Value [$]'][0])/ 
                             portfolio_df['Portfolio Value [$]'][0]) * 100

    portfolio_daily_return_df = portfolio_df.drop(columns = ['Date', 'Portfolio Value [$]', 'Portfolio daily return [$]'])
    portfolio_daily_return_df = portfolio_daily_return_df.pct_change(1) 

    expected_portfolio_return = np.sum(weights * portfolio_daily_return_df.mean() ) * 252
    
    covariance = portfolio_daily_return_df.cov() * 252 
    expected_volatility = np.sqrt(np.dot(weights.T, np.dot(covariance, weights)))
    
    rf = 0.035 #risk free rate at the end of 2022
    
    sharpe_ratio = (expected_portfolio_return - rf)/expected_volatility 
    return expected_portfolio_return, expected_volatility, sharpe_ratio, portfolio_df['Portfolio Value [$]'][-1:].values[0], return_on_investment.values[0]
In [194]:
initial_investment = 1000000
portfolio_metrics = simulation_engine(weights, initial_investment)
In [196]:
print('Expected Portfolio Annual Return = {:.2f}%'.format(portfolio_metrics[0] * 100))
print('Portfolio Standard Deviation (Volatility) = {:.2f}%'.format(portfolio_metrics[1] * 100))
print('Sharpe Ratio = {:.2f}'.format(portfolio_metrics[2]))
print('Portfolio Final Value = ${:.2f}'.format(portfolio_metrics[3]))
print('Return on Investment = {:.2f}%'.format(portfolio_metrics[4]))
Expected Portfolio Annual Return = 16.04%
Portfolio Standard Deviation (Volatility) = 17.01%
Sharpe Ratio = 0.74
Portfolio Final Value = $3213742.52
Return on Investment = 221.37%

Monte Carlo Simulations¶

In [199]:
sim_runs = 100
#n = weight_runs.shape[1]
n=10
initial_investment = 1000000

weight_runs = np.zeros((sim_runs,n))


sharpe_ratio_runs = np.zeros(sim_runs)

expected_portfolio_return_runs = np.zeros(sim_runs)

volatility_runs = np.zeros(sim_runs)

return_on_investment_runs = np.zeros(sim_runs)

final_values_runs = np.zeros(sim_runs)

for i in range(sim_runs):

    weights = portfolio_weight_generation(n)

    weight_runs[i,:] = weights
    
    expected_portfolio_return_runs[i], volatility_runs[i], sharpe_ratio_runs[i], final_values_runs[i], return_on_investment_runs[i] = simulation_engine(weights, initial_investment)
    print("Simulation Run = {}".format(i))   
    print("Weights = {}, Final Value = ${:.2f}, Sharpe Ratio = {:.2f}".format(weight_runs[i].round(3), final_values_runs[i], sharpe_ratio_runs[i]))   
    print('\n')
Simulation Run = 0
Weights = [0.09  0.066 0.113 0.006 0.003 0.184 0.123 0.141 0.174 0.103], Final Value = $3069452.18, Sharpe Ratio = 0.69


Simulation Run = 1
Weights = [0.165 0.05  0.048 0.047 0.178 0.106 0.06  0.112 0.12  0.115], Final Value = $3131939.33, Sharpe Ratio = 0.68


Simulation Run = 2
Weights = [0.166 0.189 0.132 0.028 0.048 0.048 0.13  0.006 0.136 0.117], Final Value = $3476586.59, Sharpe Ratio = 0.73


Simulation Run = 3
Weights = [0.039 0.18  0.039 0.004 0.056 0.15  0.191 0.128 0.077 0.135], Final Value = $2898777.25, Sharpe Ratio = 0.64


Simulation Run = 4
Weights = [0.026 0.168 0.13  0.074 0.128 0.135 0.052 0.125 0.052 0.111], Final Value = $3200060.54, Sharpe Ratio = 0.69


Simulation Run = 5
Weights = [0.136 0.146 0.015 0.158 0.162 0.016 0.128 0.129 0.004 0.108], Final Value = $3118306.91, Sharpe Ratio = 0.66


Simulation Run = 6
Weights = [0.125 0.085 0.189 0.04  0.075 0.096 0.053 0.096 0.093 0.148], Final Value = $3459062.25, Sharpe Ratio = 0.74


Simulation Run = 7
Weights = [0.017 0.051 0.086 0.002 0.017 0.1   0.173 0.185 0.185 0.184], Final Value = $2839560.03, Sharpe Ratio = 0.64


Simulation Run = 8
Weights = [0.031 0.155 0.181 0.007 0.141 0.024 0.067 0.159 0.092 0.143], Final Value = $3334941.37, Sharpe Ratio = 0.69


Simulation Run = 9
Weights = [0.104 0.026 0.112 0.109 0.097 0.153 0.113 0.168 0.023 0.095], Final Value = $3172094.96, Sharpe Ratio = 0.69


Simulation Run = 10
Weights = [0.205 0.024 0.046 0.22  0.    0.144 0.027 0.061 0.05  0.223], Final Value = $3128432.34, Sharpe Ratio = 0.72


Simulation Run = 11
Weights = [0.18  0.079 0.016 0.17  0.081 0.11  0.076 0.047 0.176 0.066], Final Value = $3095819.14, Sharpe Ratio = 0.71


Simulation Run = 12
Weights = [0.074 0.214 0.013 0.149 0.174 0.16  0.017 0.069 0.013 0.117], Final Value = $3031902.87, Sharpe Ratio = 0.68


Simulation Run = 13
Weights = [0.196 0.148 0.077 0.001 0.1   0.129 0.19  0.049 0.06  0.05 ], Final Value = $3358006.16, Sharpe Ratio = 0.70


Simulation Run = 14
Weights = [0.015 0.118 0.027 0.111 0.008 0.081 0.23  0.107 0.122 0.18 ], Final Value = $2796263.07, Sharpe Ratio = 0.63


Simulation Run = 15
Weights = [0.015 0.011 0.123 0.039 0.043 0.214 0.118 0.083 0.272 0.082], Final Value = $2969788.26, Sharpe Ratio = 0.67


Simulation Run = 16
Weights = [0.007 0.135 0.003 0.185 0.087 0.127 0.118 0.198 0.032 0.11 ], Final Value = $2747933.11, Sharpe Ratio = 0.62


Simulation Run = 17
Weights = [0.126 0.092 0.014 0.13  0.167 0.227 0.007 0.004 0.183 0.05 ], Final Value = $3030200.09, Sharpe Ratio = 0.70


Simulation Run = 18
Weights = [0.076 0.095 0.11  0.07  0.143 0.095 0.112 0.118 0.079 0.101], Final Value = $3204322.33, Sharpe Ratio = 0.70


Simulation Run = 19
Weights = [0.115 0.188 0.13  0.162 0.024 0.003 0.2   0.132 0.042 0.003], Final Value = $3411606.43, Sharpe Ratio = 0.69


Simulation Run = 20
Weights = [0.045 0.055 0.01  0.197 0.017 0.07  0.173 0.116 0.235 0.08 ], Final Value = $2773988.25, Sharpe Ratio = 0.64


Simulation Run = 21
Weights = [0.102 0.119 0.012 0.082 0.159 0.142 0.073 0.112 0.147 0.053], Final Value = $2963780.82, Sharpe Ratio = 0.66


Simulation Run = 22
Weights = [0.03  0.082 0.072 0.107 0.159 0.161 0.069 0.077 0.061 0.183], Final Value = $3001769.61, Sharpe Ratio = 0.69


Simulation Run = 23
Weights = [0.003 0.098 0.118 0.15  0.089 0.128 0.029 0.163 0.159 0.064], Final Value = $3044899.81, Sharpe Ratio = 0.68


Simulation Run = 24
Weights = [0.146 0.032 0.151 0.05  0.156 0.018 0.036 0.153 0.17  0.089], Final Value = $3377941.17, Sharpe Ratio = 0.70


Simulation Run = 25
Weights = [0.126 0.134 0.127 0.083 0.106 0.107 0.111 0.003 0.056 0.147], Final Value = $3396937.76, Sharpe Ratio = 0.74


Simulation Run = 26
Weights = [0.119 0.013 0.173 0.074 0.104 0.062 0.128 0.076 0.11  0.14 ], Final Value = $3407500.41, Sharpe Ratio = 0.74


Simulation Run = 27
Weights = [0.019 0.05  0.143 0.15  0.153 0.136 0.125 0.055 0.053 0.116], Final Value = $3228210.19, Sharpe Ratio = 0.71


Simulation Run = 28
Weights = [0.177 0.174 0.03  0.159 0.053 0.198 0.048 0.082 0.054 0.026], Final Value = $3171924.73, Sharpe Ratio = 0.71


Simulation Run = 29
Weights = [0.099 0.11  0.085 0.136 0.16  0.073 0.006 0.168 0.079 0.084], Final Value = $3173878.74, Sharpe Ratio = 0.68


Simulation Run = 30
Weights = [0.031 0.177 0.096 0.095 0.119 0.14  0.131 0.146 0.043 0.023], Final Value = $3135763.49, Sharpe Ratio = 0.67


Simulation Run = 31
Weights = [0.063 0.17  0.037 0.071 0.152 0.155 0.068 0.014 0.158 0.111], Final Value = $3028670.09, Sharpe Ratio = 0.69


Simulation Run = 32
Weights = [0.098 0.108 0.043 0.112 0.135 0.068 0.096 0.134 0.122 0.083], Final Value = $3047549.96, Sharpe Ratio = 0.67


Simulation Run = 33
Weights = [0.132 0.033 0.071 0.024 0.121 0.089 0.131 0.151 0.103 0.145], Final Value = $3086235.61, Sharpe Ratio = 0.67


Simulation Run = 34
Weights = [0.039 0.231 0.207 0.027 0.05  0.208 0.065 0.01  0.051 0.113], Final Value = $3481623.39, Sharpe Ratio = 0.71


Simulation Run = 35
Weights = [0.049 0.182 0.008 0.122 0.152 0.164 0.042 0.028 0.105 0.147], Final Value = $2927956.06, Sharpe Ratio = 0.68


Simulation Run = 36
Weights = [0.09  0.034 0.212 0.071 0.132 0.069 0.151 0.012 0.024 0.206], Final Value = $3538415.04, Sharpe Ratio = 0.75


Simulation Run = 37
Weights = [0.08  0.176 0.028 0.011 0.189 0.019 0.185 0.19  0.08  0.042], Final Value = $3033477.31, Sharpe Ratio = 0.62


Simulation Run = 38
Weights = [0.007 0.227 0.008 0.012 0.034 0.12  0.142 0.19  0.031 0.227], Final Value = $2728847.92, Sharpe Ratio = 0.61


Simulation Run = 39
Weights = [0.045 0.377 0.013 0.031 0.07  0.109 0.031 0.144 0.121 0.059], Final Value = $2962826.20, Sharpe Ratio = 0.63


Simulation Run = 40
Weights = [0.165 0.002 0.182 0.017 0.192 0.038 0.006 0.001 0.173 0.224], Final Value = $3528546.33, Sharpe Ratio = 0.75


Simulation Run = 41
Weights = [0.142 0.045 0.061 0.038 0.111 0.188 0.001 0.094 0.142 0.177], Final Value = $3050584.99, Sharpe Ratio = 0.70


Simulation Run = 42
Weights = [0.109 0.097 0.1   0.124 0.204 0.02  0.112 0.001 0.118 0.114], Final Value = $3345015.13, Sharpe Ratio = 0.72


Simulation Run = 43
Weights = [0.189 0.099 0.124 0.14  0.033 0.107 0.034 0.113 0.057 0.105], Final Value = $3393101.82, Sharpe Ratio = 0.74


Simulation Run = 44
Weights = [0.086 0.041 0.093 0.093 0.141 0.097 0.144 0.055 0.135 0.115], Final Value = $3158304.11, Sharpe Ratio = 0.71


Simulation Run = 45
Weights = [0.001 0.245 0.012 0.144 0.108 0.084 0.177 0.112 0.074 0.043], Final Value = $2911134.53, Sharpe Ratio = 0.63


Simulation Run = 46
Weights = [0.073 0.035 0.142 0.115 0.052 0.101 0.168 0.126 0.013 0.175], Final Value = $3216965.20, Sharpe Ratio = 0.70


Simulation Run = 47
Weights = [0.075 0.089 0.11  0.143 0.116 0.119 0.107 0.126 0.108 0.008], Final Value = $3209978.72, Sharpe Ratio = 0.70


Simulation Run = 48
Weights = [0.117 0.143 0.086 0.154 0.155 0.151 0.004 0.099 0.004 0.087], Final Value = $3265995.24, Sharpe Ratio = 0.71


Simulation Run = 49
Weights = [0.083 0.079 0.021 0.062 0.031 0.179 0.059 0.133 0.257 0.095], Final Value = $2798726.78, Sharpe Ratio = 0.65


Simulation Run = 50
Weights = [0.129 0.054 0.144 0.183 0.145 0.104 0.094 0.006 0.017 0.125], Final Value = $3462894.69, Sharpe Ratio = 0.75


Simulation Run = 51
Weights = [0.143 0.055 0.144 0.013 0.003 0.189 0.023 0.203 0.19  0.037], Final Value = $3215809.32, Sharpe Ratio = 0.69


Simulation Run = 52
Weights = [0.112 0.196 0.025 0.165 0.08  0.017 0.097 0.16  0.029 0.12 ], Final Value = $3069073.89, Sharpe Ratio = 0.67


Simulation Run = 53
Weights = [0.044 0.099 0.288 0.1   0.042 0.102 0.01  0.216 0.036 0.065], Final Value = $3591901.83, Sharpe Ratio = 0.72


Simulation Run = 54
Weights = [0.059 0.15  0.081 0.157 0.119 0.14  0.112 0.038 0.127 0.016], Final Value = $3173614.55, Sharpe Ratio = 0.70


Simulation Run = 55
Weights = [0.15  0.129 0.179 0.12  0.095 0.029 0.058 0.045 0.061 0.135], Final Value = $3588434.01, Sharpe Ratio = 0.76


Simulation Run = 56
Weights = [0.059 0.181 0.195 0.132 0.092 0.068 0.017 0.029 0.172 0.055], Final Value = $3505530.98, Sharpe Ratio = 0.74


Simulation Run = 57
Weights = [0.048 0.147 0.09  0.056 0.143 0.119 0.111 0.148 0.129 0.01 ], Final Value = $3116248.11, Sharpe Ratio = 0.67


Simulation Run = 58
Weights = [0.139 0.081 0.12  0.044 0.098 0.055 0.163 0.126 0.072 0.101], Final Value = $3313225.79, Sharpe Ratio = 0.70


Simulation Run = 59
Weights = [0.032 0.091 0.057 0.104 0.08  0.078 0.057 0.166 0.169 0.166], Final Value = $2873932.99, Sharpe Ratio = 0.66


Simulation Run = 60
Weights = [0.023 0.039 0.209 0.2   0.177 0.023 0.149 0.    0.047 0.134], Final Value = $3508831.39, Sharpe Ratio = 0.73


Simulation Run = 61
Weights = [0.108 0.06  0.149 0.143 0.059 0.162 0.014 0.154 0.078 0.074], Final Value = $3285998.64, Sharpe Ratio = 0.72


Simulation Run = 62
Weights = [0.103 0.147 0.099 0.028 0.14  0.067 0.122 0.028 0.172 0.093], Final Value = $3270988.53, Sharpe Ratio = 0.71


Simulation Run = 63
Weights = [0.07  0.081 0.051 0.063 0.065 0.08  0.208 0.016 0.229 0.137], Final Value = $2985443.35, Sharpe Ratio = 0.67


Simulation Run = 64
Weights = [0.139 0.123 0.039 0.163 0.164 0.05  0.078 0.016 0.071 0.157], Final Value = $3199000.13, Sharpe Ratio = 0.71


Simulation Run = 65
Weights = [0.072 0.036 0.01  0.148 0.181 0.149 0.095 0.091 0.128 0.089], Final Value = $2889436.61, Sharpe Ratio = 0.66


Simulation Run = 66
Weights = [0.066 0.026 0.091 0.16  0.004 0.012 0.236 0.014 0.179 0.211], Final Value = $3069398.73, Sharpe Ratio = 0.68


Simulation Run = 67
Weights = [0.198 0.111 0.072 0.078 0.198 0.006 0.118 0.172 0.004 0.042], Final Value = $3369232.00, Sharpe Ratio = 0.66


Simulation Run = 68
Weights = [0.007 0.023 0.055 0.2   0.19  0.078 0.018 0.101 0.15  0.178], Final Value = $2897900.19, Sharpe Ratio = 0.66


Simulation Run = 69
Weights = [0.174 0.019 0.033 0.073 0.032 0.11  0.146 0.155 0.12  0.138], Final Value = $2993221.42, Sharpe Ratio = 0.67


Simulation Run = 70
Weights = [0.095 0.163 0.119 0.02  0.044 0.169 0.021 0.133 0.108 0.128], Final Value = $3186952.46, Sharpe Ratio = 0.71


Simulation Run = 71
Weights = [0.098 0.204 0.086 0.021 0.018 0.13  0.094 0.16  0.06  0.129], Final Value = $3124006.20, Sharpe Ratio = 0.68


Simulation Run = 72
Weights = [0.079 0.016 0.    0.186 0.108 0.168 0.116 0.196 0.009 0.121], Final Value = $2794111.85, Sharpe Ratio = 0.62


Simulation Run = 73
Weights = [0.096 0.133 0.026 0.076 0.104 0.09  0.144 0.132 0.077 0.123], Final Value = $2982787.31, Sharpe Ratio = 0.66


Simulation Run = 74
Weights = [0.172 0.027 0.002 0.154 0.237 0.108 0.061 0.055 0.099 0.085], Final Value = $3094417.12, Sharpe Ratio = 0.67


Simulation Run = 75
Weights = [0.083 0.102 0.007 0.146 0.098 0.088 0.145 0.105 0.117 0.108], Final Value = $2910272.22, Sharpe Ratio = 0.67


Simulation Run = 76
Weights = [0.012 0.073 0.114 0.113 0.12  0.141 0.083 0.154 0.109 0.081], Final Value = $3054598.00, Sharpe Ratio = 0.68


Simulation Run = 77
Weights = [0.154 0.035 0.129 0.137 0.047 0.179 0.128 0.062 0.094 0.035], Final Value = $3343923.69, Sharpe Ratio = 0.74


Simulation Run = 78
Weights = [0.19  0.008 0.158 0.127 0.076 0.027 0.086 0.078 0.198 0.052], Final Value = $3484667.45, Sharpe Ratio = 0.74


Simulation Run = 79
Weights = [0.126 0.106 0.157 0.027 0.113 0.02  0.046 0.113 0.184 0.108], Final Value = $3395454.39, Sharpe Ratio = 0.72


Simulation Run = 80
Weights = [0.061 0.154 0.078 0.057 0.042 0.017 0.166 0.177 0.174 0.074], Final Value = $3041487.49, Sharpe Ratio = 0.65


Simulation Run = 81
Weights = [0.155 0.093 0.205 0.083 0.113 0.102 0.09  0.081 0.061 0.018], Final Value = $3650040.50, Sharpe Ratio = 0.75


Simulation Run = 82
Weights = [0.137 0.119 0.004 0.112 0.065 0.048 0.178 0.152 0.074 0.111], Final Value = $2975188.81, Sharpe Ratio = 0.66


Simulation Run = 83
Weights = [0.099 0.012 0.063 0.147 0.103 0.035 0.166 0.165 0.183 0.026], Final Value = $3040072.35, Sharpe Ratio = 0.66


Simulation Run = 84
Weights = [0.056 0.049 0.013 0.116 0.037 0.082 0.145 0.19  0.204 0.107], Final Value = $2742516.52, Sharpe Ratio = 0.63


Simulation Run = 85
Weights = [0.047 0.039 0.175 0.164 0.071 0.076 0.181 0.072 0.121 0.054], Final Value = $3338592.48, Sharpe Ratio = 0.72


Simulation Run = 86
Weights = [0.161 0.087 0.154 0.026 0.161 0.149 0.049 0.125 0.029 0.06 ], Final Value = $3470731.70, Sharpe Ratio = 0.71


Simulation Run = 87
Weights = [0.116 0.062 0.166 0.166 0.139 0.013 0.062 0.095 0.085 0.096], Final Value = $3466045.57, Sharpe Ratio = 0.74


Simulation Run = 88
Weights = [0.111 0.065 0.157 0.053 0.001 0.178 0.125 0.094 0.078 0.139], Final Value = $3287546.71, Sharpe Ratio = 0.73


Simulation Run = 89
Weights = [0.05  0.074 0.137 0.174 0.064 0.049 0.154 0.192 0.046 0.06 ], Final Value = $3209044.58, Sharpe Ratio = 0.68


Simulation Run = 90
Weights = [0.044 0.184 0.158 0.032 0.134 0.089 0.102 0.154 0.097 0.005], Final Value = $3338863.92, Sharpe Ratio = 0.68


Simulation Run = 91
Weights = [0.027 0.163 0.174 0.179 0.06  0.068 0.002 0.028 0.172 0.127], Final Value = $3349551.79, Sharpe Ratio = 0.73


Simulation Run = 92
Weights = [0.072 0.16  0.013 0.179 0.045 0.025 0.059 0.167 0.097 0.181], Final Value = $2882416.81, Sharpe Ratio = 0.66


Simulation Run = 93
Weights = [0.124 0.071 0.094 0.01  0.193 0.055 0.25  0.064 0.11  0.029], Final Value = $3301209.30, Sharpe Ratio = 0.67


Simulation Run = 94
Weights = [0.116 0.032 0.148 0.13  0.148 0.079 0.094 0.044 0.089 0.119], Final Value = $3397080.77, Sharpe Ratio = 0.74


Simulation Run = 95
Weights = [0.094 0.066 0.178 0.081 0.128 0.119 0.015 0.155 0.02  0.144], Final Value = $3377796.29, Sharpe Ratio = 0.72


Simulation Run = 96
Weights = [0.185 0.11  0.014 0.023 0.155 0.129 0.116 0.097 0.097 0.075], Final Value = $3110380.99, Sharpe Ratio = 0.67


Simulation Run = 97
Weights = [0.078 0.104 0.095 0.058 0.111 0.072 0.19  0.026 0.125 0.141], Final Value = $3187272.28, Sharpe Ratio = 0.70


Simulation Run = 98
Weights = [0.021 0.042 0.107 0.119 0.179 0.096 0.084 0.132 0.087 0.133], Final Value = $3077456.43, Sharpe Ratio = 0.68


Simulation Run = 99
Weights = [0.004 0.187 0.127 0.038 0.171 0.088 0.179 0.023 0.165 0.018], Final Value = $3257805.17, Sharpe Ratio = 0.67


In [253]:
sharpe_ratio_runs
Out[253]:
array([0.68705802, 0.67759902, 0.73184411, 0.64114971, 0.69411339,
       0.66268488, 0.74499705, 0.63512504, 0.68784824, 0.68648812,
       0.71600236, 0.70522515, 0.67939041, 0.69768789, 0.63436387,
       0.66772974, 0.61997874, 0.69532053, 0.69536666, 0.68802506,
       0.63862295, 0.66443313, 0.68696603, 0.6803914 , 0.70075526,
       0.73961134, 0.73676401, 0.70893938, 0.70751088, 0.68236447,
       0.66696501, 0.68943513, 0.67470913, 0.66913011, 0.71419393,
       0.67834893, 0.74609042, 0.61675153, 0.60959401, 0.63134499,
       0.75423752, 0.69500272, 0.72241294, 0.73830318, 0.70545709,
       0.63085639, 0.70271176, 0.69797388, 0.71044707, 0.65191536,
       0.74952076, 0.68885269, 0.66642693, 0.71593543, 0.70151882,
       0.75783011, 0.74104933, 0.66700981, 0.69806778, 0.66006645,
       0.72601808, 0.72221369, 0.70853416, 0.67118289, 0.71337311,
       0.65898187, 0.68062563, 0.65568793, 0.66054561, 0.66640597,
       0.70679692, 0.67901765, 0.62221805, 0.6639664 , 0.67195612,
       0.66521769, 0.67793132, 0.73847718, 0.7440054 , 0.72072083,
       0.65491718, 0.74541003, 0.65505378, 0.65854169, 0.62652396,
       0.71529281, 0.71114577, 0.73536064, 0.73005152, 0.67710343,
       0.678965  , 0.72989698, 0.65918224, 0.67342607, 0.74172878,
       0.71651075, 0.66879721, 0.69990279, 0.67924659, 0.67064814])
In [267]:
sharpe_ratio_runs.max()
Out[267]:
0.7578301149343443
In [269]:
sharpe_ratio_runs.argmax()
Out[269]:
55
In [271]:
weight_runs
Out[271]:
array([[8.97154292e-02, 6.56643859e-02, 1.13341367e-01, 5.53594064e-03,
        2.50411173e-03, 1.83683020e-01, 1.22597038e-01, 1.40643428e-01,
        1.73792194e-01, 1.02523086e-01],
       [1.64792182e-01, 4.97423046e-02, 4.78990063e-02, 4.69743786e-02,
        1.77672222e-01, 1.05922283e-01, 5.96065071e-02, 1.11759376e-01,
        1.20455743e-01, 1.15175998e-01],
       [1.65832315e-01, 1.88857680e-01, 1.32483746e-01, 2.77317352e-02,
        4.82868246e-02, 4.77273848e-02, 1.30494787e-01, 6.13431662e-03,
        1.35813516e-01, 1.16637695e-01],
       [3.89373116e-02, 1.79992397e-01, 3.86885483e-02, 4.13864830e-03,
        5.62093233e-02, 1.50396100e-01, 1.91123058e-01, 1.28173002e-01,
        7.69977135e-02, 1.35343898e-01],
       [2.56105011e-02, 1.67835074e-01, 1.30286745e-01, 7.40441607e-02,
        1.27895145e-01, 1.34587197e-01, 5.18205039e-02, 1.24740952e-01,
        5.24391625e-02, 1.10740559e-01],
       [1.35950196e-01, 1.45619243e-01, 1.46880914e-02, 1.57692171e-01,
        1.62288113e-01, 1.57569463e-02, 1.27856153e-01, 1.28709043e-01,
        3.73194969e-03, 1.07708094e-01],
       [1.24511681e-01, 8.54269523e-02, 1.88990874e-01, 3.95649751e-02,
        7.47345136e-02, 9.59785550e-02, 5.34481421e-02, 9.57809171e-02,
        9.34221670e-02, 1.48141222e-01],
       [1.68346425e-02, 5.09640583e-02, 8.61685380e-02, 1.61809995e-03,
        1.74466040e-02, 9.98864232e-02, 1.73223367e-01, 1.85317972e-01,
        1.84584314e-01, 1.83955981e-01],
       [3.11798343e-02, 1.54547949e-01, 1.81099456e-01, 6.72485903e-03,
        1.40629089e-01, 2.41482367e-02, 6.73406570e-02, 1.58997246e-01,
        9.20069532e-02, 1.43325721e-01],
       [1.04210116e-01, 2.59461943e-02, 1.11630765e-01, 1.08889704e-01,
        9.68674672e-02, 1.53411751e-01, 1.13225111e-01, 1.68318027e-01,
        2.25913499e-02, 9.49095155e-02],
       [2.05118400e-01, 2.38050471e-02, 4.56793203e-02, 2.20092555e-01,
        1.06710673e-06, 1.44312509e-01, 2.70544031e-02, 6.12608896e-02,
        4.97190563e-02, 2.22956753e-01],
       [1.80211385e-01, 7.86036534e-02, 1.55516669e-02, 1.70172433e-01,
        8.09346638e-02, 1.10399511e-01, 7.55723419e-02, 4.65657447e-02,
        1.76468423e-01, 6.55201772e-02],
       [7.35301114e-02, 2.14456201e-01, 1.30594658e-02, 1.49348392e-01,
        1.73888461e-01, 1.59801524e-01, 1.73358038e-02, 6.86291753e-02,
        1.31289614e-02, 1.16821905e-01],
       [1.96096361e-01, 1.48096685e-01, 7.67353178e-02, 7.79899731e-04,
        1.00098756e-01, 1.29382551e-01, 1.90324537e-01, 4.85880485e-02,
        5.97977071e-02, 5.01001371e-02],
       [1.49409966e-02, 1.18483276e-01, 2.73095701e-02, 1.10594641e-01,
        8.33294048e-03, 8.11222630e-02, 2.30118193e-01, 1.07499320e-01,
        1.21686556e-01, 1.79912245e-01],
       [1.46476384e-02, 1.05718330e-02, 1.23331391e-01, 3.89984510e-02,
        4.28183761e-02, 2.14259549e-01, 1.18195408e-01, 8.28163958e-02,
        2.72465419e-01, 8.18955380e-02],
       [6.59509791e-03, 1.34630301e-01, 2.52447419e-03, 1.84841431e-01,
        8.67089033e-02, 1.27288958e-01, 1.17599478e-01, 1.97834386e-01,
        3.21837531e-02, 1.09793217e-01],
       [1.25605464e-01, 9.22124954e-02, 1.40635093e-02, 1.30428312e-01,
        1.67492362e-01, 2.27209954e-01, 6.64561251e-03, 3.52385742e-03,
        1.83175725e-01, 4.96427078e-02],
       [7.62920846e-02, 9.52031762e-02, 1.10166212e-01, 7.01500730e-02,
        1.43409767e-01, 9.47632600e-02, 1.12098720e-01, 1.18025042e-01,
        7.88674518e-02, 1.01024213e-01],
       [1.15297960e-01, 1.88283175e-01, 1.29586175e-01, 1.61706739e-01,
        2.42924596e-02, 3.29243360e-03, 1.99634418e-01, 1.32388916e-01,
        4.20560220e-02, 3.46170176e-03],
       [4.54417242e-02, 5.52470261e-02, 9.78857145e-03, 1.97494839e-01,
        1.74529685e-02, 7.04534612e-02, 1.72923170e-01, 1.16069278e-01,
        2.34869662e-01, 8.02592986e-02],
       [1.02210203e-01, 1.18534253e-01, 1.18720086e-02, 8.16873963e-02,
        1.58681023e-01, 1.41640484e-01, 7.33981480e-02, 1.12048582e-01,
        1.47291516e-01, 5.26363861e-02],
       [3.00150962e-02, 8.16953275e-02, 7.20418504e-02, 1.07081097e-01,
        1.59046780e-01, 1.60600006e-01, 6.87203310e-02, 7.72580903e-02,
        6.10374960e-02, 1.82503926e-01],
       [2.76813366e-03, 9.77620174e-02, 1.18242290e-01, 1.49766952e-01,
        8.91865383e-02, 1.27946660e-01, 2.86861159e-02, 1.63178622e-01,
        1.58552903e-01, 6.39097671e-02],
       [1.45607619e-01, 3.17406186e-02, 1.51071710e-01, 4.96408728e-02,
        1.55857135e-01, 1.81488627e-02, 3.59166945e-02, 1.52750435e-01,
        1.70101462e-01, 8.91645904e-02],
       [1.25865138e-01, 1.34024334e-01, 1.26781905e-01, 8.30785172e-02,
        1.06281098e-01, 1.07473090e-01, 1.10509117e-01, 3.15199811e-03,
        5.61840401e-02, 1.46650762e-01],
       [1.19151758e-01, 1.31325605e-02, 1.73306333e-01, 7.36920287e-02,
        1.04019462e-01, 6.18528810e-02, 1.28410122e-01, 7.61303613e-02,
        1.10013100e-01, 1.40291394e-01],
       [1.90165483e-02, 5.00343822e-02, 1.43012446e-01, 1.49706846e-01,
        1.52664750e-01, 1.36395424e-01, 1.25314588e-01, 5.50454532e-02,
        5.25269341e-02, 1.16282630e-01],
       [1.76668552e-01, 1.73671131e-01, 2.95253689e-02, 1.58833852e-01,
        5.33093183e-02, 1.97837472e-01, 4.78960559e-02, 8.23570661e-02,
        5.35169768e-02, 2.63842061e-02],
       [9.92556006e-02, 1.10469386e-01, 8.47217384e-02, 1.36033615e-01,
        1.59579680e-01, 7.33128450e-02, 6.22991234e-03, 1.67518653e-01,
        7.91030071e-02, 8.37755629e-02],
       [3.05283777e-02, 1.77400849e-01, 9.57203497e-02, 9.47560802e-02,
        1.18520822e-01, 1.40481382e-01, 1.31227826e-01, 1.46248895e-01,
        4.25125185e-02, 2.26029004e-02],
       [6.32745284e-02, 1.69835224e-01, 3.74905253e-02, 7.08473289e-02,
        1.51813021e-01, 1.55261174e-01, 6.82469933e-02, 1.43000488e-02,
        1.57781446e-01, 1.11149711e-01],
       [9.82283744e-02, 1.08375576e-01, 4.33948984e-02, 1.12395552e-01,
        1.34518548e-01, 6.75218103e-02, 9.63365835e-02, 1.33724218e-01,
        1.22349003e-01, 8.31554377e-02],
       [1.32122248e-01, 3.30712090e-02, 7.06602565e-02, 2.39900559e-02,
        1.21486005e-01, 8.89577818e-02, 1.30834248e-01, 1.50946152e-01,
        1.03279794e-01, 1.44652251e-01],
       [3.86310121e-02, 2.30910044e-01, 2.07026959e-01, 2.65867312e-02,
        4.99007902e-02, 2.07511765e-01, 6.49287972e-02, 1.02473939e-02,
        5.08210549e-02, 1.13435453e-01],
       [4.89786823e-02, 1.82201959e-01, 8.05243025e-03, 1.22268665e-01,
        1.52446114e-01, 1.64053826e-01, 4.15161979e-02, 2.81355622e-02,
        1.05281241e-01, 1.47065322e-01],
       [8.95836940e-02, 3.38716833e-02, 2.12196660e-01, 7.11594633e-02,
        1.31678256e-01, 6.87185047e-02, 1.50819692e-01, 1.16407114e-02,
        2.40795147e-02, 2.06251820e-01],
       [8.01959256e-02, 1.75690304e-01, 2.83603571e-02, 1.13626514e-02,
        1.89362885e-01, 1.88027394e-02, 1.85016369e-01, 1.89777671e-01,
        7.98171203e-02, 4.16139779e-02],
       [7.06762319e-03, 2.27039276e-01, 8.38398988e-03, 1.24056302e-02,
        3.44058368e-02, 1.20307096e-01, 1.42018545e-01, 1.90069164e-01,
        3.10902112e-02, 2.27212628e-01],
       [4.45280360e-02, 3.77084704e-01, 1.25755464e-02, 3.11990985e-02,
        6.99402169e-02, 1.09477701e-01, 3.06228421e-02, 1.44151038e-01,
        1.21431165e-01, 5.89896524e-02],
       [1.64932998e-01, 2.43314874e-03, 1.82183849e-01, 1.73521825e-02,
        1.91586773e-01, 3.83303286e-02, 5.61278955e-03, 7.35116648e-04,
        1.72771414e-01, 2.24061399e-01],
       [1.41871940e-01, 4.49628911e-02, 6.10592645e-02, 3.83066002e-02,
        1.11375480e-01, 1.87813631e-01, 1.38259468e-03, 9.41340870e-02,
        1.42474907e-01, 1.76618605e-01],
       [1.09011388e-01, 9.74917555e-02, 1.00167785e-01, 1.23850941e-01,
        2.04298322e-01, 1.96726776e-02, 1.12490134e-01, 1.36676408e-03,
        1.17936051e-01, 1.13714182e-01],
       [1.88517874e-01, 9.93499055e-02, 1.23907018e-01, 1.40377436e-01,
        3.25091720e-02, 1.06690541e-01, 3.36942899e-02, 1.13420373e-01,
        5.69872506e-02, 1.04546139e-01],
       [8.55123088e-02, 4.09713856e-02, 9.32482129e-02, 9.28775079e-02,
        1.40997115e-01, 9.72980779e-02, 1.44346945e-01, 5.46173251e-02,
        1.34707074e-01, 1.15424048e-01],
       [1.45116091e-03, 2.44726110e-01, 1.21500886e-02, 1.44250520e-01,
        1.08160095e-01, 8.40357293e-02, 1.77158740e-01, 1.11846803e-01,
        7.36566013e-02, 4.25641530e-02],
       [7.31638310e-02, 3.52224634e-02, 1.42413211e-01, 1.15213802e-01,
        5.17471398e-02, 1.00533003e-01, 1.67741989e-01, 1.26020612e-01,
        1.26077882e-02, 1.75336161e-01],
       [7.48494629e-02, 8.85124784e-02, 1.10291036e-01, 1.42758716e-01,
        1.15619463e-01, 1.18785477e-01, 1.06725224e-01, 1.25965707e-01,
        1.08007272e-01, 8.48516307e-03],
       [1.17363689e-01, 1.43464271e-01, 8.60362643e-02, 1.53565893e-01,
        1.54939497e-01, 1.50650289e-01, 4.16361817e-03, 9.91460893e-02,
        3.52539785e-03, 8.71449916e-02],
       [8.30764033e-02, 7.93770529e-02, 2.07654801e-02, 6.24954630e-02,
        3.10702759e-02, 1.78593045e-01, 5.91782211e-02, 1.33231430e-01,
        2.56862977e-01, 9.53496510e-02],
       [1.28931211e-01, 5.39961135e-02, 1.44156332e-01, 1.83149201e-01,
        1.44993463e-01, 1.03945369e-01, 9.35441290e-02, 5.89751582e-03,
        1.68065528e-02, 1.24580113e-01],
       [1.42813219e-01, 5.45053307e-02, 1.44275876e-01, 1.29124179e-02,
        3.43832168e-03, 1.89091719e-01, 2.29495225e-02, 2.02812961e-01,
        1.90345180e-01, 3.68554529e-02],
       [1.12355919e-01, 1.95591557e-01, 2.51521978e-02, 1.64702539e-01,
        7.96656653e-02, 1.69170731e-02, 9.67213302e-02, 1.59501968e-01,
        2.92864133e-02, 1.20105337e-01],
       [4.43976134e-02, 9.87057396e-02, 2.87545162e-01, 9.96130385e-02,
        4.24072408e-02, 1.01669278e-01, 9.58532113e-03, 2.15529042e-01,
        3.55793407e-02, 6.49682248e-02],
       [5.89866045e-02, 1.49933460e-01, 8.06227389e-02, 1.56890162e-01,
        1.19314353e-01, 1.40362020e-01, 1.12396658e-01, 3.82139963e-02,
        1.26791800e-01, 1.64882075e-02],
       [1.50453233e-01, 1.28920488e-01, 1.79020637e-01, 1.19658285e-01,
        9.45116146e-02, 2.86297113e-02, 5.78075428e-02, 4.49907383e-02,
        6.06618587e-02, 1.35345891e-01],
       [5.94378823e-02, 1.81157500e-01, 1.95163205e-01, 1.32265312e-01,
        9.19927956e-02, 6.79565816e-02, 1.67596631e-02, 2.85781940e-02,
        1.71989632e-01, 5.46992354e-02],
       [4.84129376e-02, 1.46685460e-01, 8.98322759e-02, 5.56418852e-02,
        1.43296370e-01, 1.18807776e-01, 1.10530705e-01, 1.47686814e-01,
        1.29036712e-01, 1.00690635e-02],
       [1.38569629e-01, 8.14414575e-02, 1.19744323e-01, 4.40946552e-02,
        9.82525084e-02, 5.49431428e-02, 1.63196380e-01, 1.26206570e-01,
        7.23061679e-02, 1.01245168e-01],
       [3.23853224e-02, 9.11556670e-02, 5.67364993e-02, 1.04382617e-01,
        7.97867185e-02, 7.82627036e-02, 5.68732255e-02, 1.65521014e-01,
        1.69258698e-01, 1.65637535e-01],
       [2.29362952e-02, 3.89237100e-02, 2.09227065e-01, 1.99557022e-01,
        1.77344247e-01, 2.25458618e-02, 1.49031508e-01, 2.67029460e-04,
        4.65974381e-02, 1.33569824e-01],
       [1.07790524e-01, 5.99454935e-02, 1.49309068e-01, 1.42507147e-01,
        5.85141572e-02, 1.62498362e-01, 1.35005720e-02, 1.54417553e-01,
        7.75456505e-02, 7.39714727e-02],
       [1.03324363e-01, 1.47371641e-01, 9.86625790e-02, 2.80542900e-02,
        1.39755652e-01, 6.69071379e-02, 1.22194469e-01, 2.83362444e-02,
        1.72326601e-01, 9.30670229e-02],
       [6.96631409e-02, 8.14329163e-02, 5.08364153e-02, 6.33896043e-02,
        6.50736318e-02, 7.98776817e-02, 2.07766997e-01, 1.58182550e-02,
        2.29116590e-01, 1.37024768e-01],
       [1.38535049e-01, 1.23484473e-01, 3.94645089e-02, 1.63007992e-01,
        1.63851781e-01, 4.95498766e-02, 7.77551232e-02, 1.60637400e-02,
        7.13292148e-02, 1.56958243e-01],
       [7.18142287e-02, 3.63710183e-02, 9.89520791e-03, 1.48224003e-01,
        1.81239780e-01, 1.49184417e-01, 9.54662501e-02, 9.06999245e-02,
        1.28011546e-01, 8.90936247e-02],
       [6.59850612e-02, 2.64194682e-02, 9.08860429e-02, 1.60396987e-01,
        3.67165165e-03, 1.21170942e-02, 2.36162223e-01, 1.41943349e-02,
        1.79007378e-01, 2.11159759e-01],
       [1.98409077e-01, 1.10711816e-01, 7.20225447e-02, 7.79943005e-02,
        1.98266941e-01, 5.65588950e-03, 1.18448313e-01, 1.72240950e-01,
        4.42220655e-03, 4.18279603e-02],
       [7.32114383e-03, 2.34521447e-02, 5.54419592e-02, 1.99758115e-01,
        1.89735470e-01, 7.80273495e-02, 1.75871319e-02, 1.00631728e-01,
        1.50370687e-01, 1.77674271e-01],
       [1.74290184e-01, 1.94197404e-02, 3.26995443e-02, 7.33730976e-02,
        3.16259750e-02, 1.09834761e-01, 1.45633143e-01, 1.54901405e-01,
        1.20038578e-01, 1.38183572e-01],
       [9.52205410e-02, 1.62837464e-01, 1.18731922e-01, 2.03725947e-02,
        4.37025141e-02, 1.69151687e-01, 2.07871210e-02, 1.32899864e-01,
        1.08147336e-01, 1.28148957e-01],
       [9.77293941e-02, 2.04366620e-01, 8.64689184e-02, 2.06757408e-02,
        1.80031312e-02, 1.29938431e-01, 9.41319875e-02, 1.60175653e-01,
        5.97524991e-02, 1.28757625e-01],
       [7.91195240e-02, 1.55289521e-02, 4.01935314e-04, 1.86405912e-01,
        1.07939955e-01, 1.67986587e-01, 1.16492088e-01, 1.96073030e-01,
        8.77601608e-03, 1.21276001e-01],
       [9.63376324e-02, 1.32626417e-01, 2.58444001e-02, 7.58277772e-02,
        1.03776737e-01, 9.03199030e-02, 1.44004057e-01, 1.32062537e-01,
        7.65643440e-02, 1.22636195e-01],
       [1.72360661e-01, 2.67034400e-02, 1.65502307e-03, 1.53908406e-01,
        2.36836003e-01, 1.07837160e-01, 6.14706388e-02, 5.48019477e-02,
        9.91321022e-02, 8.52946181e-02],
       [8.32069919e-02, 1.02184704e-01, 7.30903542e-03, 1.46403641e-01,
        9.84741502e-02, 8.78717454e-02, 1.45143704e-01, 1.05082395e-01,
        1.16805528e-01, 1.07518106e-01],
       [1.17121280e-02, 7.29352916e-02, 1.14378699e-01, 1.12653119e-01,
        1.19650319e-01, 1.41379577e-01, 8.26278471e-02, 1.54341108e-01,
        1.08897145e-01, 8.14247675e-02],
       [1.53688750e-01, 3.50185009e-02, 1.28597601e-01, 1.37159945e-01,
        4.67727913e-02, 1.79456398e-01, 1.27655904e-01, 6.22494465e-02,
        9.40687276e-02, 3.53319359e-02],
       [1.89837337e-01, 7.74658878e-03, 1.58436020e-01, 1.27311345e-01,
        7.56601008e-02, 2.68051989e-02, 8.62713575e-02, 7.79151065e-02,
        1.97535822e-01, 5.24811231e-02],
       [1.26237621e-01, 1.06311263e-01, 1.57240104e-01, 2.67241232e-02,
        1.12912267e-01, 1.95671274e-02, 4.61836321e-02, 1.12642503e-01,
        1.84052815e-01, 1.08128543e-01],
       [6.11227307e-02, 1.54163016e-01, 7.79137534e-02, 5.68311030e-02,
        4.21566646e-02, 1.68135227e-02, 1.65848416e-01, 1.77047731e-01,
        1.73890452e-01, 7.42126112e-02],
       [1.54511583e-01, 9.33947681e-02, 2.05086699e-01, 8.28162649e-02,
        1.12615042e-01, 1.01743030e-01, 8.97496089e-02, 8.14908359e-02,
        6.05787498e-02, 1.80134178e-02],
       [1.36988384e-01, 1.19251521e-01, 3.96805887e-03, 1.11797813e-01,
        6.53209976e-02, 4.81614749e-02, 1.77571260e-01, 1.52087778e-01,
        7.36495765e-02, 1.11203137e-01],
       [9.90479106e-02, 1.18957549e-02, 6.31832082e-02, 1.46601633e-01,
        1.03406313e-01, 3.53851309e-02, 1.66331741e-01, 1.65214535e-01,
        1.83092443e-01, 2.58413296e-02],
       [5.61519470e-02, 4.94701498e-02, 1.30564997e-02, 1.15887141e-01,
        3.73129737e-02, 8.18079722e-02, 1.45314785e-01, 1.90493793e-01,
        2.03818553e-01, 1.06686186e-01],
       [4.74446403e-02, 3.87797150e-02, 1.74857877e-01, 1.63892314e-01,
        7.10418073e-02, 7.59060948e-02, 1.80718270e-01, 7.21234687e-02,
        1.20769580e-01, 5.44662335e-02],
       [1.60720047e-01, 8.73760222e-02, 1.53733821e-01, 2.62758960e-02,
        1.60979159e-01, 1.49389126e-01, 4.87774990e-02, 1.24585126e-01,
        2.85514279e-02, 5.96118759e-02],
       [1.16126387e-01, 6.23731313e-02, 1.65604625e-01, 1.66289841e-01,
        1.38951401e-01, 1.27506164e-02, 6.18028000e-02, 9.52353762e-02,
        8.52058186e-02, 9.56600031e-02],
       [1.11104702e-01, 6.45885107e-02, 1.57026133e-01, 5.34373774e-02,
        8.57650333e-04, 1.77889140e-01, 1.24775949e-01, 9.36072856e-02,
        7.79300946e-02, 1.38783158e-01],
       [5.01062999e-02, 7.37888206e-02, 1.37158152e-01, 1.74366839e-01,
        6.39592555e-02, 4.90203990e-02, 1.53613770e-01, 1.91567450e-01,
        4.63733015e-02, 6.00457131e-02],
       [4.39864588e-02, 1.84308564e-01, 1.58358379e-01, 3.15597633e-02,
        1.34295920e-01, 8.93454878e-02, 1.02004189e-01, 1.54476474e-01,
        9.69884075e-02, 4.67635592e-03],
       [2.71658257e-02, 1.63027378e-01, 1.74219957e-01, 1.78642604e-01,
        6.03194796e-02, 6.83567161e-02, 1.60627284e-03, 2.82873232e-02,
        1.71841124e-01, 1.26533321e-01],
       [7.24892974e-02, 1.60276668e-01, 1.28983501e-02, 1.79400350e-01,
        4.48013515e-02, 2.51840702e-02, 5.92064847e-02, 1.67191871e-01,
        9.71928846e-02, 1.81358673e-01],
       [1.24419777e-01, 7.13213622e-02, 9.39018986e-02, 1.02293740e-02,
        1.92614951e-01, 5.46056147e-02, 2.50016645e-01, 6.36776873e-02,
        1.09885326e-01, 2.93273644e-02],
       [1.15719802e-01, 3.21864509e-02, 1.48482815e-01, 1.30356016e-01,
        1.48205010e-01, 7.86031052e-02, 9.35325266e-02, 4.40450300e-02,
        8.94266551e-02, 1.19442589e-01],
       [9.44801343e-02, 6.56803390e-02, 1.77588708e-01, 8.14198055e-02,
        1.27641193e-01, 1.18730614e-01, 1.52812704e-02, 1.54989462e-01,
        2.02686783e-02, 1.43919795e-01],
       [1.85131895e-01, 1.10221868e-01, 1.36505483e-02, 2.27803676e-02,
        1.54779446e-01, 1.29066143e-01, 1.15655878e-01, 9.70988919e-02,
        9.65772506e-02, 7.50377125e-02],
       [7.80738450e-02, 1.04316837e-01, 9.46285897e-02, 5.84407003e-02,
        1.10592785e-01, 7.23295841e-02, 1.89739523e-01, 2.60216741e-02,
        1.24956919e-01, 1.40899543e-01],
       [2.09546961e-02, 4.18686535e-02, 1.07496957e-01, 1.18741782e-01,
        1.79308467e-01, 9.58204392e-02, 8.39166036e-02, 1.32178764e-01,
        8.67530833e-02, 1.32960554e-01],
       [3.90728544e-03, 1.86757153e-01, 1.27106946e-01, 3.75768391e-02,
        1.70672639e-01, 8.82855788e-02, 1.79385173e-01, 2.30063654e-02,
        1.64932050e-01, 1.83699698e-02]])
In [273]:
weight_runs[sharpe_ratio_runs.argmax(),:]
Out[273]:
array([0.15045323, 0.12892049, 0.17902064, 0.11965829, 0.09451161,
       0.02862971, 0.05780754, 0.04499074, 0.06066186, 0.13534589])
In [275]:
optimal_portfolio_return, optimal_volatility, optimal_sharpe_ratio, highest_final_value, optimal_return_on_investment = simulation_engine(weight_runs[sharpe_ratio_runs.argmax(),:], initial_investment)
In [277]:
print('Best Portfolio Metrics Based on {} Monte Carlo Simulation Runs:'.format(sim_runs))
print('  - Portfolio Expected Annual Return = {:.02f}%'.format(optimal_portfolio_return * 100))
print('  - Portfolio Standard Deviation (Volatility) = {:.02f}%'.format(optimal_volatility * 100))
print('  - Sharpe Ratio = {:.02f}'.format(optimal_sharpe_ratio))
print('  - Final Value = ${:.02f}'.format(highest_final_value))
print('  - Return on Investment = {:.02f}%'.format(optimal_return_on_investment))
Best Portfolio Metrics Based on 100 Monte Carlo Simulation Runs:
  - Portfolio Expected Annual Return = 17.57%
  - Portfolio Standard Deviation (Volatility) = 18.57%
  - Sharpe Ratio = 0.76
  - Final Value = $3588434.01
  - Return on Investment = 258.84%
In [304]:
sim_out_df = pd.DataFrame({'Volatility' :volatility_runs.tolist(),'Portfolio_return' : expected_portfolio_return_runs.tolist(),
                          'Sharpe_ratio' :sharpe_ratio_runs.tolist()})
sim_out_df
Out[304]:
Volatility Portfolio_return Sharpe_ratio
0 0.176224 0.156076 0.687058
1 0.186944 0.161673 0.677599
2 0.186535 0.171515 0.731844
3 0.183671 0.152761 0.641150
4 0.183495 0.162366 0.694113
... ... ... ...
95 0.186645 0.168733 0.716511
96 0.190815 0.162616 0.668797
97 0.178514 0.159942 0.699903
98 0.180363 0.157511 0.679247
99 0.191640 0.163523 0.670648

100 rows × 3 columns

In [308]:
import plotly.graph_objects as go
fig = px.scatter(sim_out_df, x = 'Volatility', y = 'Portfolio_return', color = 'Sharpe_ratio', size = 'Sharpe_ratio', hover_data = ['Sharpe_ratio'] )
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
In [312]:
fig = px.scatter(sim_out_df, x = 'Volatility', y = 'Portfolio_return', color = 'Sharpe_ratio', size = 'Sharpe_ratio', hover_data = ['Sharpe_ratio'] )
fig.add_trace(go.Scatter(x = [optimal_volatility], y = [optimal_portfolio_return], mode = 'markers', name = 'Optimal Point', marker = dict(size=[40], color = 'green')))
fig.update_layout(coloraxis_colorbar = dict(y = 0.7, dtick = 5))
fig.update_layout({'plot_bgcolor': "white"})
fig.show()
In [ ]: